package beans.taskprocess;

class TaskDispatcher implements Runnable
{
	private final TaskRunner[] __taskRunners;
	private boolean __needStop;
	private final int __numTaskRunners;
	private final long __sleepTime;

	TaskDispatcher(int numThreads, int threadPriotiry, long sleepTime)
	{
		int i;
		ThreadGroup threadGroup;

		__numTaskRunners = numThreads;
		__taskRunners = new TaskRunner[__numTaskRunners];
		__sleepTime = sleepTime;
		threadGroup = Thread.currentThread().getThreadGroup();
		for (i = 0; i < __numTaskRunners; i++)
		{
			final TaskRunner taskRunner;
			final Thread thread;

			taskRunner = new TaskRunner();
			__taskRunners[i] = taskRunner;
			thread = new Thread(threadGroup, taskRunner);
			thread.setDaemon(true);
			thread.setPriority(threadPriotiry);
			thread.start();
		}
	}

	public void run()
	{
		while (true)
		{
			try
			{
				Thread.sleep(__sleepTime);
			}
			catch (InterruptedException exception)
			{
				// Who is the idiot who stops me?
			}
			if (__needStop) // java ensures atomicity
			{
				final int count;

				count = this.countIdleTaskRunners();
				if (count != __numTaskRunners)
				{
					System.out.println("Waiting for " + (__numTaskRunners - count) + " tasks to end");
					continue;
				}
				else
				{
					System.out.println("Shutting down!");
					break;
				}
			}
			// killForTimeout( );
			while (true)
			{
				final TaskRunner taskRunner;

				taskRunner = this.findIdleTaskRunner();
				if (taskRunner != null)
				{
					final TaskNode taskNode;

					try
					{
						taskNode = TaskManager.getTaskNode();
					}
					catch (IndexOutOfBoundsException exception)
					{
						// I don't have any task to do.
						break;
					}
					catch (RuntimeException exception)
					{
						break;
					}
					if (taskNode != null)
						taskRunner.doTask(taskNode);
					else
						break;
				}
				else
					break;
			}
		}
	}

	private TaskRunner findIdleTaskRunner()
	{
		int i;

		for (i = 0; i < __numTaskRunners; i++)
		{
			final TaskRunner taskRunner;

			taskRunner = __taskRunners[i];
			if (taskRunner.status() == TaskRunner.STATUS_IDLE)
				return taskRunner;
		}
		return null;
	}

	private int countIdleTaskRunners()
	{
		int count;
		int i;

		count = 0;
		for (i = 0; i < __numTaskRunners; i++)
		{
			final TaskRunner taskRunner;

			taskRunner = __taskRunners[i];
			if (taskRunner.status() == TaskRunner.STATUS_IDLE)
				count++;
		}
		return count;
	}

	@SuppressWarnings("unused")
	private void killForTimeout()
	{
		int i;

		for (i = 0; i < __numTaskRunners; i++)
			__taskRunners[i].killIfNeed();
	}

	void stop()
	{
		__needStop = true; // java ensures atomicity
	}
}
